use rustcloud_registry::{
    HealthCheckManager, AutoRemovalManager, AutoRemovalConfig, RemovalStrategy, 
    LoggingEventListener, AutoRemovalEventListener, AutoRemovalEvent
};
use rustcloud_core::{ServiceInstance, HealthCheck, HealthCheckType, RegistryConfig, RegistryType};
use std::time::Duration;
use std::sync::Arc;
use async_trait::async_trait;

/// 自定义事件监听器示例
pub struct CustomEventListener {
    name: String,
}

impl CustomEventListener {
    pub fn new(name: impl Into<String>) -> Self {
        Self {
            name: name.into(),
        }
    }
}

#[async_trait]
impl AutoRemovalEventListener for CustomEventListener {
    async fn on_event(&self, event: AutoRemovalEvent) {
        match event {
            AutoRemovalEvent::InstanceRemoved { instance, reason } => {
                println!("[{}] 🚨 实例已自动摘除: {} - 原因: {}", self.name, instance, reason);
                
                // 这里可以添加自定义逻辑，如：
                // 1. 发送告警通知
                // 2. 记录到数据库
                // 3. 触发自动扩容
                // 4. 更新监控面板
            }
            AutoRemovalEvent::RemovalSkipped { instance, reason } => {
                println!("[{}] ⚠️ 跳过摘除实例: {} - 原因: {}", self.name, instance, reason);
            }
            AutoRemovalEvent::RemovalFailed { instance, error } => {
                println!("[{}] ❌ 摘除失败: {} - 错误: {}", self.name, instance, error);
            }
        }
    }
}

/// 模拟注册中心（用于测试）
pub struct MockRegistry {
    instances: Arc<tokio::sync::RwLock<Vec<ServiceInstance>>>,
}

impl MockRegistry {
    pub fn new() -> Self {
        Self {
            instances: Arc::new(tokio::sync::RwLock::new(Vec::new())),
        }
    }
    
    pub async fn add_instance(&self, instance: ServiceInstance) {
        let mut instances = self.instances.write().await;
        instances.push(instance);
    }
}

#[async_trait::async_trait]
impl rustcloud_core::ServiceRegistry for MockRegistry {
    async fn register(&self, instance: ServiceInstance) -> rustcloud_core::ServiceResult<()> {
        let mut instances = self.instances.write().await;
        instances.push(instance);
        Ok(())
    }
    
    async fn deregister(&self, instance: ServiceInstance) -> rustcloud_core::ServiceResult<()> {
        let mut instances = self.instances.write().await;
        instances.retain(|i| {
            !(i.service_id == instance.service_id && i.host == instance.host && i.port == instance.port)
        });
        println!("📤 从注册中心摘除实例: {}", instance);
        Ok(())
    }
    
    async fn discover(&self, service_name: &str) -> rustcloud_core::ServiceResult<Vec<ServiceInstance>> {
        let instances = self.instances.read().await;
        Ok(instances.iter()
            .filter(|i| i.service_id == service_name)
            .cloned()
            .collect())
    }
    
    async fn health_check(&self, service_name: &str) -> rustcloud_core::ServiceResult<Vec<ServiceInstance>> {
        let instances = self.discover(service_name).await?;
        Ok(instances.into_iter().filter(|i| i.healthy).collect())
    }
    
    async fn watch(&self, _service_name: &str) -> rustcloud_core::ServiceResult<Box<dyn rustcloud_core::ServiceWatcher + Send>> {
        Err(rustcloud_core::ServiceError::NotImplemented("Mock registry doesn't support watching".to_string()))
    }
}

/// 综合示例：健康检查 + 自动摘除
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 初始化日志
    tracing_subscriber::init();
    
    println!("🚀 启动服务治理综合示例");
    println!("=====================================");
    
    // 创建模拟注册中心
    let registry = Arc::new(MockRegistry::new());
    
    // 创建健康检查管理器
    let health_manager = Arc::new(HealthCheckManager::new());
    
    // 创建自动摘除配置
    let auto_removal_config = AutoRemovalConfig {
        enabled: true,
        strategy: RemovalStrategy::Combined {
            strategies: vec![
                RemovalStrategy::ConsecutiveFailures { threshold: 3 },
                RemovalStrategy::FailureRate { threshold: 0.8, min_checks: 5 },
                RemovalStrategy::UnhealthyDuration { threshold: Duration::from_secs(30) },
            ],
        },
        check_interval: Duration::from_secs(10),
        cooldown_period: Duration::from_secs(60),
        allow_remove_last_instance: false,
        min_instances: 1,
    };
    
    // 创建自动摘除管理器
    let auto_removal = AutoRemovalManager::new(
        auto_removal_config,
        registry.clone(),
        health_manager.clone(),
    );
    
    // 添加事件监听器
    auto_removal.add_event_listener(Arc::new(LoggingEventListener)).await;
    auto_removal.add_event_listener(Arc::new(CustomEventListener::new("AlertSystem"))).await;
    
    // 创建测试服务实例
    let instances = vec![
        ServiceInstance::new("user-service", "127.0.0.1", 8080, "http"),
        ServiceInstance::new("user-service", "127.0.0.1", 8081, "http"),
        ServiceInstance::new("user-service", "127.0.0.1", 8082, "http"),
    ];
    
    // 注册服务实例
    for instance in &instances {
        registry.register(instance.clone()).await?;
        println!("📋 注册服务实例: {}", instance);
    }
    
    // 为每个实例配置健康检查（模拟不同的健康状态）
    for (i, instance) in instances.iter().enumerate() {
        let health_check = match i {
            0 => {
                // 实例1：TCP健康检查，连接localhost应该成功
                HealthCheck {
                    check_type: HealthCheckType::Tcp,
                    endpoint: format!("{}:{}", instance.host, instance.port),
                    interval: Duration::from_secs(5),
                    timeout: Duration::from_secs(2),
                    failure_threshold: 3,
                    success_threshold: 1,
                }
            },
            1 => {
                // 实例2：HTTP健康检查，访问不存在的端口会失败
                HealthCheck {
                    check_type: HealthCheckType::Http {
                        path: "/health".to_string(),
                        method: "GET".to_string(),
                    },
                    endpoint: format!("http://{}:{}/health", instance.host, instance.port),
                    interval: Duration::from_secs(3),
                    timeout: Duration::from_secs(2),
                    failure_threshold: 2,
                    success_threshold: 1,
                }
            },
            2 => {
                // 实例3：脚本健康检查，ping本地主机应该成功
                HealthCheck {
                    check_type: HealthCheckType::Script {
                        command: if cfg!(target_os = "windows") {
                            "ping -n 1 127.0.0.1".to_string()
                        } else {
                            "ping -c 1 127.0.0.1".to_string()
                        },
                    },
                    endpoint: "".to_string(),
                    interval: Duration::from_secs(8),
                    timeout: Duration::from_secs(5),
                    failure_threshold: 2,
                    success_threshold: 1,
                }
            },
            _ => unreachable!(),
        };
        
        println!("🏥 为实例 {} 启动健康检查", instance);
        
        // 启动健康检查（实例2会因为端口未开放而失败）
        health_manager.start_health_check(
            instance.clone(),
            health_check,
            Some(Box::new(|instance: ServiceInstance, is_healthy: bool| {
                if is_healthy {
                    println!("✅ 实例 {} 恢复健康", instance);
                } else {
                    println!("❌ 实例 {} 变为不健康", instance);
                }
            })),
        ).await?;
    }
    
    // 启动自动摘除监控
    auto_removal.start_monitoring("user-service".to_string()).await?;
    
    println!("\n⏰ 监控已启动，等待健康检查结果...");
    println!("预期结果：");
    println!("- 实例1 (TCP检查) 应该保持健康");
    println!("- 实例2 (HTTP检查) 应该失败并被自动摘除");
    println!("- 实例3 (Script检查) 应该保持健康");
    println!("\n按 Ctrl+C 停止监控");
    
    // 定期显示状态
    let status_task = {
        let health_manager = health_manager.clone();
        let registry = registry.clone();
        tokio::spawn(async move {
            let mut interval = tokio::time::interval(Duration::from_secs(15));
            loop {
                interval.tick().await;
                
                println!("\n📊 当前状态报告:");
                println!("================");
                
                // 显示注册的实例
                match registry.discover("user-service").await {
                    Ok(instances) => {
                        println!("📍 注册中心实例数: {}", instances.len());
                        for instance in instances {
                            println!("  - {}", instance);
                        }
                    }
                    Err(e) => println!("❌ 获取实例失败: {}", e),
                }
                
                // 显示健康状态
                let health_states = health_manager.get_all_health_states().await;
                println!("🏥 健康检查状态:");
                for (instance_key, state) in health_states {
                    println!("  - {}: {} (检查:{}, 失败:{}, 连续失败:{})", 
                             instance_key, 
                             if state.is_healthy { "✅ 健康" } else { "❌ 不健康" },
                             state.total_checks,
                             state.total_failures,
                             state.consecutive_failures);
                }
                println!("================\n");
            }
        })
    };
    
    // 等待用户中断
    tokio::signal::ctrl_c().await?;
    
    println!("\n🛑 正在停止监控...");
    
    // 停止状态报告任务
    status_task.abort();
    
    // 停止自动摘除监控
    auto_removal.stop_monitoring("user-service").await;
    
    // 停止所有健康检查
    for instance in &instances {
        health_manager.stop_health_check(instance).await;
    }
    
    // 关闭管理器
    auto_removal.shutdown().await;
    health_manager.shutdown().await;
    
    // 显示摘除记录
    let removal_records = auto_removal.get_removal_records().await;
    if !removal_records.is_empty() {
        println!("\n📋 摘除记录:");
        for record in removal_records {
            println!("  - 实例: {} | 时间: {:?} | 原因: {}", 
                     record.instance, 
                     record.removal_time, 
                     record.reason);
        }
    }
    
    println!("👋 服务治理综合示例结束");
    Ok(())
}

#[cfg(test)]
mod tests {
    use super::*;
    use tokio::time::{sleep, Duration};
    
    #[tokio::test]
    async fn test_auto_removal_integration() {
        let registry = Arc::new(MockRegistry::new());
        let health_manager = Arc::new(HealthCheckManager::new());
        
        // 配置快速摘除以便测试
        let config = AutoRemovalConfig {
            enabled: true,
            strategy: RemovalStrategy::ConsecutiveFailures { threshold: 2 },
            check_interval: Duration::from_secs(1),
            cooldown_period: Duration::from_secs(5),
            allow_remove_last_instance: false,
            min_instances: 1,
        };
        
        let auto_removal = AutoRemovalManager::new(config, registry.clone(), health_manager.clone());
        
        // 添加一个健康的实例和一个不健康的实例
        let healthy_instance = ServiceInstance::new("test-service", "8.8.8.8", 53, "tcp");
        let unhealthy_instance = ServiceInstance::new("test-service", "192.168.99.99", 12345, "tcp");
        
        registry.register(healthy_instance.clone()).await.unwrap();
        registry.register(unhealthy_instance.clone()).await.unwrap();
        
        // 启动健康检查
        let health_check = HealthCheck {
            check_type: HealthCheckType::Tcp,
            endpoint: "".to_string(),
            interval: Duration::from_secs(1),
            timeout: Duration::from_secs(1),
            failure_threshold: 2,
            success_threshold: 1,
        };
        
        health_manager.start_health_check(healthy_instance.clone(), health_check.clone(), None).await.unwrap();
        health_manager.start_health_check(unhealthy_instance.clone(), health_check, None).await.unwrap();
        
        // 启动自动摘除监控
        auto_removal.start_monitoring("test-service".to_string()).await.unwrap();
        
        // 等待足够长的时间让不健康的实例被摘除
        sleep(Duration::from_secs(10)).await;
        
        // 检查结果
        let remaining_instances = registry.discover("test-service").await.unwrap();
        
        // 应该只剩下健康的实例
        assert_eq!(remaining_instances.len(), 1);
        assert_eq!(remaining_instances[0].host, "8.8.8.8");
        
        // 检查摘除记录
        let removal_records = auto_removal.get_removal_records().await;
        assert_eq!(removal_records.len(), 1);
        assert_eq!(removal_records[0].instance.host, "192.168.99.99");
        
        // 清理
        auto_removal.stop_monitoring("test-service").await;
        health_manager.stop_health_check(&healthy_instance).await;
    }
}